package org.lwz.space.dao.impl;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.lwz.space.dao.BaseDao;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * Created by Liaowz on 2015/11/25.
 */
@SuppressWarnings("unchecked")
public class BaseDaoImpl<T> implements BaseDao<T> {

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public T load(Serializable id) {
        return (T) getSession().load(getEntityClass(), id);
    }

    @Override
    public T get(Serializable id) {
        return (T) getSession().get(getEntityClass(), id);
    }

    @Override
    public void save(T t) {
        getSession().save(t);
    }

    @Override
    public void delete(T t) {
        getSession().delete(t);
    }

    @Override
    public void delete(Serializable id) {
        T load = (T) getSession().load(getEntityClass(), id);
        this.delete(load);
    }

    @Override
    public List<T> list() {
        DetachedCriteria criteria = createDetachedCriteria();
        return findByCriteria(criteria);
    }

    @Override
    public void update(T t) {
        getSession().update(t);
    }

    public DetachedCriteria createDetachedCriteria() {
        return DetachedCriteria.forClass(getEntityClass());
    }

    @SuppressWarnings("rawtypes")
    public List findByCriteria(DetachedCriteria criteria) {
        Criteria executableCriteria = criteria.getExecutableCriteria(this.getSession());
        return executableCriteria.list();
    }

    public Class<T> getEntityClass() {
        return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }


}
